package demos;

import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class ConnectionPool {
	private int size = 5;
	private volatile List<Integer> connections;
	private Semaphore sem;
	
	public ConnectionPool() {
		sem = new Semaphore(size, false);
		connections = new LinkedList<>();
		
		for(int i = 0; i < size; i++)
			connections.add(1);
	}
	
	public ConnectionPool(int size) {
		this.size = size;
		sem = new Semaphore(size, false);
		connections = new LinkedList<>();
		
		for(int i = 0; i < size; i++)
			connections.add(1);
	}
	
	public synchronized Integer getConnection() {
		boolean tag = false;
		try {
			tag = sem.tryAcquire(200, TimeUnit.MILLISECONDS);
		} catch (InterruptedException e) {
			throw new RuntimeException(e);
		}
		if(tag)
			return connections.remove(0);
		else
			return null;
	}
	
	public synchronized void releaseConnection(Integer conn) {
		connections.add(conn);
		sem.release();
	}
	
	public static void main(String[] args) {
		ConnectionPool pool = new ConnectionPool(10);
		Random rand = new Random();
		ExecutorService exec = Executors.newCachedThreadPool();
		for(int i = 0; i < 20; i++) {
			exec.execute(new Runnable() {
				
				@Override
				public void run() {
					try {
						Integer i = pool.getConnection();
						if(i != null) {
							System.out.println(Thread.currentThread().getName() + "获得连接");
							TimeUnit.MILLISECONDS.sleep(rand.nextInt(1000));
							pool.releaseConnection(i);
							System.out.println(Thread.currentThread().getName() + "释放连接");
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					
				}
			});
		}
		exec.shutdown();
	}
}
